home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / ifdef.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  11KB  |  463 lines

  1. /* Ifdef - remove #ifdefs        Author: Warren Toomey */
  2.  
  3. /* Ifdef: Remove unwanted ifdefs from C code          */
  4. /* Written by Warren Toomey - 1989              */
  5. /* You may freely copy or give away this source as    */
  6. /* Long as this notice remains intact.              */
  7. /* 9/16/89 - Added usage() before getopt() - meb      */
  8.  
  9. #include <sys/types.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13.  
  14. /* Definition of structures and constants used in ifdef.c  */
  15.  
  16. /* Types of symbols */
  17. #define DEF      1        /* Symbol is defined    */
  18. #define UNDEF      2        /* Symbol isn't defined */
  19. #define IGN      3        /* Ignore this symbol unless defined       */
  20.  
  21. /* Redef mode values */
  22. #define MUTABLE   1        /* Symbol can change defined <-> undefined */
  23. #define IMMUTABLE 2        /* Symbol can't change as above            */
  24.  
  25. /* Processing modes */
  26. #define NO    0        /* Don't process */
  27. #define YES    1        /* Process */
  28.  
  29. /* Ignore (IGN), ignore but process */
  30. struct DEFINE {
  31.   char *symbol;            /* SLL of defined symbols. The redef  */
  32.   char type;            /* field indicates if this symbol can */
  33.   char redef;            /* change from defined <-> undefined. */
  34.   struct DEFINE *next;        /* Type is DEF or UNDEF.          */
  35. };
  36.  
  37. /* Global variables & structures */
  38. FILE *zin;            /* Input file for processing  */
  39. struct DEFINE *defptr;        /* Defined symbols SLL        */
  40. struct DEFINE *defend;        /* Ptr to last node in defptr */
  41. struct DEFINE *deftemp;        /* Ptr to last found node     */
  42. int line = 1;            /* Current line number        */
  43. int table = 0;            /* Don't normally want a table */
  44.  
  45. char fgetarg(stream, cbuf)    /* Get next arg from file into cbuf, */
  46. FILE *stream;            /* returning the character that      */
  47. char *cbuf;            /* terminated it. Cbuf returns NULL  */
  48. {                /* if no arg. EOF is returned if no  */
  49.   char ch;            /* args left in file.                */
  50.   int i;
  51.  
  52.   i = 0;
  53.   cbuf[i] = 0;
  54.  
  55.   while (((ch = fgetc(stream)) == ' ') || (ch == '\t') || (ch == '\n'))
  56.     if (ch == '\n') return(ch);    /* Bypass leading */
  57.   /* Whitespace     */
  58.   if (feof(stream)) return(EOF);
  59.  
  60.   cbuf[i++] = ch;
  61.  
  62.   while (((ch = fgetc(stream)) != ' ') && (ch != '\t') && (ch != '\n'))
  63.     cbuf[i++] = ch;        /* Get the argument */
  64.  
  65.   cbuf[i] = 0;
  66.   return(ch);
  67. }
  68.  
  69.  
  70. find(sym)
  71. char *sym;
  72. {                /* Return DEF if defined else UNDEF */
  73.   char found = 0;        /* IGN if symbol is ignored  */
  74.   /* 0 if not in the list */
  75.  
  76.   deftemp = defptr;
  77.   while (deftemp) {        /* Search for the symbol */
  78.     if (!strcmp(deftemp->symbol, sym))
  79.         return(deftemp->type);    /* Setting up the type */
  80.     deftemp = deftemp->next;
  81.   }
  82.   return(0);
  83. }
  84.  
  85.  
  86.  
  87. #define Define(x,y)    defit(x,y,DEF)
  88. #define Undefine(x,y)    defit(x,y,UNDEF)
  89. #define Ignore(x,y)    defit(x,y,IGN)
  90.  
  91. defit(sym, redef, type)        /* Add symbol to the define list */
  92. char *sym;
  93. char redef;            /* Mode: MUTABLE etc      */
  94. char type;            /* Type: DEF, UNDEF, IGN  */
  95. {
  96.   struct DEFINE *temp;
  97.   char c;
  98.  
  99.   c = find(sym);        /* First try finding the symbol */
  100.   if (type == c) return;    /* Return if already declared */
  101.   if (c) {            /* We have to move if from DEF <-> UNDEF */
  102.     if (deftemp->redef == IMMUTABLE)
  103.         return;
  104.     else {
  105.         deftemp->type = type;
  106.         deftemp->redef = redef;
  107.     }
  108.   } else {            /* We must create a struct & add it */
  109.     /* Malloc room for the struct */
  110.     if ((temp = (struct DEFINE *) malloc(sizeof(struct DEFINE))) == NULL) {
  111.         fprintf(stderr, "ifdef: could not malloc\n");
  112.         exit(1);
  113.     }
  114.  
  115.     /* Malloc room for symbol */
  116.     if ((temp->symbol = (char *) malloc(strlen(sym) + 1)) == NULL) {
  117.         fprintf(stderr, "ifdef: could not malloc\n");
  118.         exit(1);
  119.     }
  120.     strcpy(temp->symbol, sym);    /* Copy symbol into struct      */
  121.     temp->redef = redef;    /* and set its redef mode too   */
  122.     temp->type = type;    /* as well as making it defined */
  123.  
  124.  
  125.     /* Now add to the SLL */
  126.     if (defptr == NULL)    /* If first node set  */
  127.         defptr = temp;    /* the pointers to it */
  128.     else
  129.         defend->next = temp;    /* else add it to the */
  130.     defend = temp;        /* end of the list.   */
  131.   }
  132. }
  133.  
  134.  
  135.  
  136. stop()
  137. {                /* Stop: Tidy up at EOF */
  138.   if (table) printtable();
  139.   fclose(zin);
  140.   exit(0);
  141. }
  142.  
  143. #define Goto    { line++; if (ch!='\n') gotoeoln(zin); }
  144. #define Print    { line++; if (ch!='\n')  prteoln(zin); }
  145.  
  146. gotoeoln(file)            /* Go to the end of the line */
  147. FILE *file;
  148. {
  149.   int ch;
  150.   while ((ch = fgetc(zin)) != '\n')
  151.     if (ch == EOF) stop();
  152. }
  153.  
  154.  
  155. prteoln(file)            /* Print to the end of the line */
  156. FILE *file;
  157. {
  158.   int ch;
  159.   while ((ch = fgetc(zin)) != '\n')
  160.     if (ch == EOF)
  161.         stop();
  162.     else
  163.         putchar(ch);
  164.   putchar('\n');
  165. }
  166.  
  167.  
  168. printtable()
  169. {                /* Print the defines in the SLL */
  170.   struct DEFINE *temp;
  171.  
  172.   printf("Defined\n\n");
  173.  
  174.   temp = defptr;
  175.   while (temp) {
  176.     if (temp->type == DEF) printf("%s\n", temp->symbol);
  177.     temp = temp->next;
  178.   }
  179.  
  180.   printf("\n\nUndefined\n\n");
  181.  
  182.   temp = defptr;
  183.   while (temp) {
  184.     if (temp->type == UNDEF) printf("%s\n", temp->symbol);
  185.     temp = temp->next;
  186.   }
  187. }
  188.  
  189. getendif()
  190. {                /* Find matching endif when ignoring */
  191.   char word[80];        /* Buffer for symbols */
  192.   int ch;
  193.   int skip;            /* Number of skipped #ifdefs         */
  194.  
  195.   skip = 1;
  196.  
  197.   while (1) {
  198.     /* Scan through the file looking for starting lines */
  199.     if ((ch = fgetc(zin)) == EOF)
  200.         stop();        /* Get first char on the line */
  201.     if (ch != '#') {    /* If not a # ignore line     */
  202.         putchar(ch);
  203.         Print;
  204.         continue;
  205.     }
  206.     ch = fgetarg(zin, word);/* Get the word after the # */
  207.  
  208.     if (!strcmp(word, "ifdef")) skip++;    /* Keep track of ifdefs & */
  209.     if (!strcmp(word, "endif")) skip--;    /* endifs          */
  210.  
  211.     printf("#%s%c", word, ch);    /* Print the line out       */
  212.     Print;
  213.     if (!skip) return('\n');/* If matching endif, return */
  214.   }
  215. }
  216.  
  217.  
  218. gettable()
  219. {
  220. /* Get & print a table of defines etc.  */
  221.  
  222.   char word[80];        /* Buffer for symbols */
  223.   int ch;
  224.   int proc;            /* Should we be processing this bit?    */
  225.   int skip;            /* Number of skipped #ifdefs         */
  226.  
  227.   proc = 1;
  228.   skip = 0;
  229.  
  230.   while (1) {
  231.     /* Scan through the file looking for starting lines */
  232.     if ((ch = fgetc(zin)) == EOF)
  233.         stop();        /* Get first char on the line */
  234.     if (ch != '#') {    /* If not a # ignore line     */
  235.         Goto;
  236.         continue;
  237.     }
  238.     ch = fgetarg(zin, word);/* Get the word after the # */
  239.  
  240.     if (!strcmp(word, "define") && proc) {    /* Define: Define the */
  241.         ch = fgetarg(zin, word);    /* symbol, and goto   */
  242.         Define(word, MUTABLE);    /* the end of line    */
  243.         Goto;
  244.         continue;
  245.     }
  246.     if (!strcmp(word, "undef") && proc) {    /* Undef: Undefine the */
  247.         ch = fgetarg(zin, word);    /* symbol, and goto    */
  248.         Undefine(word, MUTABLE);    /* the end of line     */
  249.         Goto;
  250.         continue;
  251.     }
  252.     if (!strcmp(word, "ifdef")) {    /* Ifdef:            */
  253.         if (!proc)    /* If not processing */
  254.             skip++;    /* skip it           */
  255.         else {
  256.             ch = fgetarg(zin, word);    /* Get the symbol */
  257.             if (find(word) != DEF) {
  258.                 Undefine(word, MUTABLE);    /* undefine it */
  259.                 proc = 0;    /* & stop processing */
  260.             }
  261.         }
  262.         Goto;
  263.         continue;
  264.     }
  265.     if (!strcmp(word, "ifndef")) {    /* Ifndef:      */
  266.         if (!proc)    /* If not processing */
  267.             skip++;    /* skip the line     */
  268.         else {
  269.             ch = fgetarg(zin, word);    /* Get the symbol */
  270.             if (find(word) == DEF)    /* If defined, stop */
  271.                 proc = 0;    /* processing       */
  272.         }
  273.         Goto;
  274.         continue;
  275.     }
  276.     if (!strcmp(word, "else") && !skip) {    /* Else: Flip processing */
  277.         proc = !proc;
  278.         Goto;
  279.         continue;
  280.     }
  281.     if (!strcmp(word, "endif")) {    /* Endif: If no skipped */
  282.         if (!skip)    /* on, else decrement the */
  283.             proc = 1;    /* number of skips        */
  284.         else
  285.             skip--;
  286.         Goto;
  287.         continue;
  288.     }
  289.     Goto;            /* else ignore the line */
  290.   }
  291. }
  292.  
  293.  
  294.  
  295. parse()
  296. {                /* Parse & remove ifdefs from C source */
  297.   char word[80];        /* Buffer for symbols */
  298.   int ch;
  299.   int proc;            /* Should we be processing this bit?    */
  300.   int skip;            /* Number of skipped #ifdefs         */
  301.  
  302.   proc = 1;
  303.   skip = 0;
  304.  
  305.   while (1) {
  306.     /* Scan through the file looking for starting lines */
  307.     if ((ch = fgetc(zin)) == EOF)
  308.         stop();        /* Get first char on the line */
  309.     if (ch != '#')
  310.         if (proc) {    /* If not # and  we're processing */
  311.             putchar(ch);    /* then print the line */
  312.             Print;
  313.             continue;
  314.         } else {
  315.             Goto;    /* else just skip the line  */
  316.             continue;
  317.         }
  318.  
  319.     ch = fgetarg(zin, word);/* Get the word after the # */
  320.  
  321.     if (!strcmp(word, "define") && proc) {    /* Define: Define the */
  322.         ch = fgetarg(zin, word);    /* symbol, and goto   */
  323.         Define(word, MUTABLE);    /* the end of line    */
  324.         printf("#define %s%c", word, ch);
  325.         Print